
#pragma once

#include "../Main.h"

#include "DragDrop.h"
#include "InputKeys.h"

enum ANCHORS
{
	ANCHOR_TOP		            = 0x01,
	ANCHOR_BOTTOM	            = 0x02,

	ANCHOR_LEFT		            = 0x04,
    ANCHORS_TOPLEFT             = 0x05,
    ANCHORS_BOTTOMLEFT          = 0x06,

	ANCHOR_RIGHT	            = 0x08,
    ANCHORS_TOPRIGHT            = 0x09,
    ANCHORS_BOTTOMRIGHT         = 0x0A,

    ANCHORS_ALL                 = 0x0F,

    ANCHOR_PARENT_RELATIVE      = 0x10,
    ANCHORS_ALL_PARENT_RELATIVE = 0x1F
};

template <class Widget> class TypedList;

class Widget
{
	public:

		virtual ~Widget							( );
	
		virtual void SetName					( const char* szName ) { m_szName = szName; };	
		virtual void SetPosition				( const u_int uX, const u_int uY );
		virtual void SetSize					( const u_int uWidth, const u_int uHeight );
		virtual void SetAnchors					( const u_int uAnchors );
		
		virtual void Update						( );
		virtual void Render						( );

		virtual void DeleteChildren				( );
		
		virtual void SetVisible					( const bool bVisible )	{ m_bVisible = bVisible; }
		virtual bool IsVisible					( )						{ return m_bVisible; }

		virtual bool IsModified					( )					{ return m_bModified; }
		virtual void SetModified				( bool bModified )	{ m_bModified = bModified; }

		virtual bool MouseInWidget				( ) const;
		virtual bool MouseInAreaOfWidget		( u_int uX, u_int uY, u_int uWidth, u_int uHeight ) const;

		virtual bool CanHaveChildren			( ) const;
		virtual Widget* FindChildWidgetAt		( const u_int uX, const u_int uY );
		virtual TypedList<Widget>* GetChildren	( ) { return m_pxChildren; }
		
		virtual u_int GetResizedX				( ) const;
		virtual u_int GetResizedY				( ) const;
		virtual u_int GetResizedWidth			( ) const;
		virtual u_int GetResizedHeight			( ) const;
		
		virtual const char*  GetName			( ) const { return m_szName; }
		virtual u_int GetOriginalX				( ) const { return m_uPositionX; }
		virtual u_int GetOriginalY				( ) const { return m_uPositionY; }
		virtual u_int GetOriginalWidth			( ) const { return m_uWidth; }
		virtual u_int GetOriginalHeight			( ) const { return m_uHeight; }

		virtual Widget* GetParent				( ) const { return m_pxParent; }

		// Drag drop functions
		virtual void SetBeginDragDropCallback	( const BeginDragDropCallback pfnBeginDragDrop );
		virtual void SetDragOverCallback		( const DragOverCallback pfnDragOver );
		virtual void SetEndDragDropCallback		( const EndDragDropCallback pfnEndDragDrop );

		virtual BeginDragDropCallback	GetBeginDragDropCallback	( ) { return m_pfnOnBeginDragDrop; }
		virtual DragOverCallback		GetDragOverCallback			( ) { return m_pfnOnDragOver; }
		virtual EndDragDropCallback		GetEndDragDropCallback		( ) { return m_pfnOnEndDragDrop; }

		bool HasFocus() { return ( s_pxFocus == this ); }
	
		virtual void SetDefaultCursor( const INPUT_MOUSE_CURSOR xDefaultCursor ) { m_xDefaultCursor = xDefaultCursor; };

		virtual void SetUserData( const void* pUserData, const u_int uDataSize );
		virtual void GetUserData( void* &pUserData, u_int &uDataSize ) const;
		virtual const void* GetUserData() const;

	protected:

		virtual void AddChild			( Widget* pxChild );
		virtual void RemoveChild		( Widget* pxChild );

		virtual bool CanGetFocus() { return true; }
		virtual void OnGetFocus() {};
		virtual void OnLoseFocus() {};

		virtual void ScissorToWidget( bool bScissor );

		Widget ( Widget* pxParent );
		
		const char*				m_szName;
		u_int					m_uAnchors;
		TypedList<Widget>*		m_pxChildren;
		Widget*					m_pxParent;

		u_int					m_uPositionX;
		u_int					m_uPositionY;

		u_int					m_uWidth;
		u_int					m_uHeight;
	
		u_int					m_uWindowOriginalWidth;
		u_int					m_uWindowOriginalHeight;

		bool					m_bVisible;
		bool					m_bModified;
	
		INPUT_MOUSE_CURSOR		m_xDefaultCursor;
		
		BeginDragDropCallback	m_pfnOnBeginDragDrop;
		DragOverCallback		m_pfnOnDragOver;
		EndDragDropCallback		m_pfnOnEndDragDrop;

		void* m_pUserData;
		u_int m_uUserDataSize;

		static Widget* s_pxFocus;

	private:

		Widget () {}
};

// eof
